'use strict';
Object.defineProperty(exports, '__esModule', {
  value: true,
});
const fs = require('fs');
const path = require('path');
import stripJsonComments from './strip-json-comments';
import { isArray, isEmpty } from 'lodash';

const VIRTUAL_ID   = '\0virtual:vite-plugin-uni-read-pages';
const RESOLVED_ID  = 'virtual:vite-plugin-uni-read-pages';

class TransformPages {
  constructor({ includes, pagesJsonDir }) {
    this.includes      = includes;
    this.pagesJsonDir  = path.resolve(pagesJsonDir); 
    this.reload(); 
  }
 
  reload() {
    const raw       = fs.readFileSync(this.pagesJsonDir,  'utf-8');
    const json      = JSON.parse(stripJsonComments(raw));
	this.uniPagesJSON = json;
    this.routes      = [].concat(
      this.getPagesRoutes(json.pages), 
      this.getSubPackagesRoutes(json.subPackages  || [])
    );
    this.tabbar      = this.getTabbarRoutes(json.tabBar?.list  || []);
    this.routesMap   = this.transformPathToKey(this.routes); 
  }
	
  /**
   * 通过读取pages.json文件 生成直接可用的routes
   */
  getPagesRoutes(pages = this.uniPagesJSON.pages, rootPath = null) {
    let routes = [];
    for (let i = 0; i < pages.length; i++) {
      const item = pages[i];
      let route = {};
      for (let j = 0; j < this.includes.length; j++) {
        const key = this.includes[j];
        let value = item[key];
        if (key === 'path') {
          value = rootPath ? `/${rootPath}/${value}` : `/${value}`;
        }
        if (key === 'aliasPath' && i == 0 && rootPath == null) {
          route[key] = route[key] || '/';
        } else if (value !== undefined) {
          route[key] = value;
        }
      }
      routes.push(route);
    }
    return routes;
  }
  /**
   * 解析小程序分包路径
   */
  getSubPackagesRoutes() {
    if (!(this.uniPagesJSON && this.uniPagesJSON.subPackages)) {
      return [];
    }
    const subPackages = this.uniPagesJSON.subPackages;
    let routes = [];
    for (let i = 0; i < subPackages.length; i++) {
      const subPages = subPackages[i].pages;
      const root = subPackages[i].root;
      const subRoutes = this.getPagesRoutes(subPages, root);
      routes = routes.concat(subRoutes);
    }
    return routes;
  }

  getTabbarRoutes() {
    if (!(this.uniPagesJSON && this.uniPagesJSON.tabBar && this.uniPagesJSON.tabBar.list)) {
      return [];
    }
    const tabbar = this.uniPagesJSON.tabBar.list;
    let tabbarMap = [];
    tabbar.forEach((bar) => {
      tabbarMap.push('/' + bar.pagePath);
    });
    return tabbarMap;
  }

  transformPathToKey(list) {
    if (!isArray(list) || isEmpty(list)) {
      return [];
    }
    let map = {};
    list.forEach((i) => {
      map[i.path] = i;
    });
    return map;
  }
}

function pluginFactory({ pagesJsonDir, includes }) {
  const defaultIncludes = ['path', 'aliasPath', 'name'];
  includes              = [...defaultIncludes, ...includes];
 
  let inst;
 
  const getInst = () => (inst ||= new TransformPages({ pagesJsonDir, includes }));
 
  return ({
    name: 'vite-plugin-uni-read-pages',
 
    /* ---- virtual module ---- */
    resolveId(id) { return id === RESOLVED_ID ? VIRTUAL_ID : null; },
    
    load(id) {
      if (id !== VIRTUAL_ID) return null;
 
      const { routes, routesMap, tabbar } = getInst();
      return `
        export const ROUTES     = ${JSON.stringify(routes)}; 
        export const ROUTES_MAP = ${JSON.stringify(routesMap)}; 
        export const TABBAR     = ${JSON.stringify(tabbar)}; 
      `;
    },
 
    /* ---- HMR ---- */
    configureServer(server) {
      server.watcher.add(getInst().pagesJsonDir); 
 
      server.watcher.on('change',  filePath => {
        if (filePath !== getInst().pagesJsonDir) return;
 
        try   { inst.reload();  }
        catch (e) { return server.config.logger.error(e);  }
 
        // HMR：让虚拟模块失效并重新拉取 
        server.moduleGraph.invalidateModule( 
          server.moduleGraph.getModuleById(VIRTUAL_ID) 
        );
      });
    },
  });
}
exports.default = pluginFactory;
